<?php
namespace control;
/*
*用车记录类
*/

class carRecordClass extends adIndexClass
{
    private const page = 'carRecord';
    private const table = 'car_record';
    private const title = '用车记录';
	public array $stateOption = ['草稿', '审核中', '已通过'];

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            default:
                $tr = [
                    'orderNo'      => [
                        'name'  => "单据编号",
                        'width' => 150,
                        'sort' => 1,
                    ],
                    'staffId' => [
                        'name'  => "用车人",
                        'width' => 100,
                    ],
                    'department'  => [
                        'name'  => "用车人部门",
                        'width' => 100,
                    ],
                    'startDate'         => [
                        'name'  => '用车时间',
                        'width' => 100,
                        'sort' => 1,
                    ],
                    'carNo'          => [
                        'name'  => '车牌号',
                        'width' => 100,
                    ],
                    'lineStart'    => [
                        'name'  => '出车线路',
                        'width' => 100,
                        'sort' => 1,
                    ],
                    'lineEnd'    => [
                        'name'  => '返程线路',
                        'width' => 100,
                        'sort' => 1,
                    ],
                    'kilometre'    => [
                        'name'  => '公里数合计',
                        'width' => 100,
                        'sort' => 1,
                    ],
                    'reason'    => [
                        'name'  => '用车事由',
                        'width' => 150,
                    ],
                    'state'    => [
                        'name'  => '审批状态',
                        'width' => 100,
                        'sort' => 1,
                    ],
                    'isBack'    => [
                        'name'  => '还车状态',
                        'width' => 100,
                        'sort' => 1,
                    ],
                    'endDate'    => [
                        'name'  => '预计还车时间',
                        'width' => 130,
                        'sort' => 1,
                    ],
                    'backDate'    => [
                        'name'  => '实际还车时间',
                        'width' => 130,
                        'sort' => 1,
                    ],
                    'factMileage'    => [
                        'name'  => '实际里程',
                        'width' => 100,
                        'sort' => 1,
                    ]
                ];
        }
        return $tr;
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "单据编号" => text(array("name" => "orderNo")),
                    "用车人"     => selectMultiple(["name" => "staffId", 'table' => " staff", 'sqlId' => 'stid', 'sqlField' => 'name', 'class' => 'width200']),
                    '部门' => selectMultiple(["name" => "departmentId", 'table' => " department", 'sqlId' => 'id', 'sqlField' => 'name', 'class' => 'width200']),
                ],
                [
                    "用车时间" => text(array("name" => "createTime", 'laydate' => ['type' => 'date', 'range' => '~'])),
                    "状态" => select(["name" => "state", 'option' => $this->stateOption]),
                ]
            ]
        ],1);
        //返回
        if(!$isAsync){
            return $html;
        }else{
            return json_encode(['html'=>$html],320);
        }
    }

	/*列表-查询条件*/
	public function home()
	{
        $html = $this->homeOptions(false);
        //控件
        $button = "";
        $url = root . "control/adIndex.html?cla=" . self::page;
        if ($this->power(self::page, "edit")) {
            $button .= "<span onclick=\"layer('".self::page."','edit')\" class='spanButton'>新增</span>\n";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del'})\">删除</span>\n";
        }
		//返回
		return $this->homeFun($this->search($html,layout: 'pop',toolButton: $button));
	}

	/*客户列表-查询结果*/
	public function homeSearch()
	{
		//like查询数组
		$like = array(
			"orderNo" => $this->post('orderNo'),//车辆编号
		);
		//全等查询数组
		$equal = array(
			"state" => $this->post('state'),//状态
		);
		$and   = "";
		if (!empty($this->post('departmentId'))) {
			//部门
			$and .= " and stid in (select stid from staff where jobId in (select id from job where departmentId = '{$this->post('departmentId')}')) ";
		}
		if ($this->post('createTime')) {
            $and .= self::timeComparison($this->post('createTime'), 'date', 'startDate');
		}

		//查看自己
		$and .= $this->seeSelf(self::page, 'staffId');

        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'time',
            "sort" => $this->post('list_sort') ?: "desc",
            "array"   => array(),
        ));
		//获取查询结果
		$where                         = search(array("like" => $like, "=" => $equal)) . $and;

		$page                          = $this->page(array("table" => self::table, "where" => $where, "order" => $orderBy['orderBy']));
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "listId")
        );
		//获取记录
		$url = root . "control/adIndex.html?cla=" . self::page;
		foreach ($page['array'] as $array) {
			//列表控件
			$dominate   = array(
				"box"    => array("name" => "listId", "value" => $array['id']),
                "edit" => array("title" => "编辑", "click" => "layer('" . self::page . "','edit',{id:'" . $array['id'] . "'})"),
				"detail" => array("title" => self::title . "详情", "click" => "newIframe('" . self::title . "详情','" . $url . "&fun=detail&id=" . $array['id'] . "')"),
			);
			if ($array['state'] !='草稿'){
			    unset($dominate['edit']);
            }
			if ($array['isBack'] =='否'){
                $dominate['backCar'] = array("title" => "还车", "click" => "layer('" . self::page . "','back',{id:'".$array['id']."'})");
            }
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case "staffId":
                        $row[] = self::findStaff($array['staffId']);
                        break;
                    case "department":
                        $job        = query('job', " id = '$array[jobId]'");
                        $department = query('department', " id = '$job[departmentId]'");
                        $row[] = $department['name'];
                        break;
                    case "carNo":
                        $car        = query('car', " id = '$array[carId]'");
                        $row[] = $car['shortName'] . $car['carNo'];
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
		}
		//控件
		$button = "";
        $total = [
            'kilometre'=>find(array('table' => self::table, 'sum' => 'kilometre', 'where' => $where)),
        ];
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton,"width" => 120),
            "orderBySign" => $orderBy,
            "page" => $page['para'],
            "total" => $total,
        ));
		//返回
		$json['html'] = $page['hint'] . $button . "<form name='listForm'>" . $li . "</form>" . $page['button'] . clear;
		return json_encode($json, 320);
	}

    /**
     * 还车
     * @return bool|string
     */
	public function back(): bool|string
    {
        $insure = query(self::table, " id = '{$this->post('id')}'");
        //生成表单
        $html = $this->layerEdit(array("table" => array(
            array(
                must . "还车日期：" => text(array("name" => "backDate", 'laydate' => [], "value" => $insure['backDate'])),
                must ."实际里程：" =>text(array("name" => "factMileage", "value" => $insure['factMileage'])),
            ),
            array(
                "备注：" =>textarea(array('name' => 'backText', 'class' => 'textarea', 'value' => $insure['backText']))
            ),
        ),

        ));
        //返回
        return $this->layer(array(
            "title" => "还车",
            "height" => 250,
            "width" => 900,
            "html" => $html,
            'button' => '<button class="button" onclick="subForm(\'carRecordBackForm\',root+\'control/adIndex.html?cla=carRecord&fun=backEdit\')">保存</button>'
        ));
    }

    /**
     * 还车
     * @return bool|string
     */
    public function backEdit(): bool|string
    {

        $id = $this->post('id');
        $field = [
            'isBack'=>'是',
            'backDate' => $this->post('backDate'),
            'factMileage' => $this->post('factMileage'),
            'backText' => $this->post('backText'),
        ];
        $annotation = [
            'backDate' => '还车日期',
            'factMileage' => '实际里程',
        ];
        $rules = [
            'backDate' => 'required',
            'factMileage' => 'required',
        ];
        // 校验是否符合规则
        $vt = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
            goto resp;
        }
        $where = " id = '$id' ";
        $info = query(self::table, $where);
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有编辑" . self::title . "的权限";
        }elseif(empty($info['id'])){
            $json['warn'] = '未找到此用车记录';
        }elseif($info['state'] !='已通过'){
            $json['warn'] = '此用车记录还未审核通过';
        }elseif($info['isBack'] =='是'){
            $json['warn'] = '此用车已归还';
        } else {
            $json['warn'] = static::update([
                "table" => self::table,
                "field" => $field,
                "where" => $where
            ]);
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] .  "归还了" . self::title . " id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn'] = 2;
            }
        }
        resp:
        return json_encode($json, 320);
    }

	/**
	 * 编辑页
	 *
	 * @return string
	 */
    public function edit()
    {
        $id = $this->post('id') ?:self::getId();
        $info   = query(self::table, " id = '" . $id. "' ");
        $option = [];
        $all    = find(array('table' => 'car', "where" => " state ='正常' and id not in (select carId from car_record where state = '已通过' and isBack = '否')", 'field' => " CONCAT(shortName,carNo) as carNo,id"));
        foreach ($all['array'] as $array) {
            $option[$array['id']] = $array['carNo'];
        }
        $where = $this->seeSelf(self::page);
        //表单
        $html = $this->layerEdit([
            "table" => [
                [
                    must . "用车人：" => selectMultiple(["name" => "staffId", 'table' => " staff", 'where' => $where, 'sqlId' => 'stid', 'sqlField' => 'name', 'title' => '用车人', 'value' => $info['staffId']]),
                    must . "用车时间：" => text(["name" => "startDate", 'laydate' => [], 'class' => 'text', "value" => $info['startDate']]),
                ],
                [
                    "还车时间：" => text(["name" => "endDate", 'laydate' => [], 'class' => 'text', "value" => $info['endDate']]),
                    must . "车牌号：" => selectMultiple(["name" => "carId", 'title' => '车牌号', 'option' => $option, "value" => $info['carId']]),
                ],
                [
                    must . "出车路线：" => text(["name" => "lineStart", 'class' => 'text', "value" => $info['lineStart']]),
                    must . "返程路线：" => text(["name" => "lineEnd", 'class' => 'text', "value" => $info['lineEnd']]),
                ],
                [
                    "公里数合计：" => text(["name" => "kilometre", 'class' => 'text', "value" => $info['kilometre']]),
                ],
                [
                    must . "用车事由：" => textarea(["name" => "reason", 'class' => 'textarea', "value" => $info['reason']]),
                ],
            ],
        ]);
        //返回
        return $this->layer(array("title" => L('job.button.editor').self::title, "height" => 400, "html" => $html));
    }

	public function editEdit()
	{
		$id         = $this->post('id') ?: self::getId();
		$field      = [
			'staffId'    => $this->post('staffId'),
			'startDate'  => $this->post('startDate'),
			'endDate'    => $this->post('endDate'),
			'carId'      => $this->post('carId'),
			'lineStart'  => $this->post('lineStart'),
			'lineEnd'    => $this->post('lineEnd'),
			'kilometre'  => $this->post('kilometre'),
			'reason'     => $this->post('reason'),
		];
		$annotation = [
			'staffId'   => '用车人',
			'startDate' => '用车时间',
			'carId'     => '车牌号',
			'lineStart' => '出车路线',
			'lineEnd'   => '返程路线',
			'reason'    => '用车事由',
		];
		$rules      = [
			'staffId'   => 'required',
			'startDate' => 'required',
			'carId'     => 'required',
			'lineStart' => 'required',
			'lineEnd'   => 'required',
			'reason'    => 'required',
		];
		// 校验是否符合规则
		$vt     = new \verify();
		$result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
		if ($result === false) {
			$json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
			goto resp;
		}
		//判断
		if (!$this->power(self::page, "edit")) {
			$json['warn'] = "你没有编辑" . self::title . "的权限";
		} elseif ($this->is_cross($field['startDate'], $field['endDate'], $field['carId'])) {
            //判断提交时间是否和已申请的会员室时间存在重合
            $json['warn'] = '您所提交的使用时间和其他人有重合';
        }  else {
			$where          = " id = '$id' ";
			$info           = query(self::table, $where);
			$staff          = query('staff', " stid = '{$field['staffId']}'");
			$field['jobId'] = $staff['jobId'];
			if (!$info['id']) {
				$department   = query('department', " id = '{$this->controlJob['departmentId']}'");
				$userNo       = codeTemplateClass::generateCode(self::page,[
                    'prefix' => 'YCSQ' . date('Ymd'),
                    'table'  => self::table,
                    'field'  => 'orderNo',
                    'where'  => '',
                ],$field);
				$field        = array_merge($field, [
					'id'       => $id,
					'orderNo'  => $userNo,
					'deptName' => $department['name'],
					'stid'     => $this->control['stid'],
					'state'    => '草稿',
					'time'     => $this->time,
				]);
				$json['warn'] = static::insert(["table" => self::table, "field" => $field]);
			} else {
				$json['warn'] = static::update([
					"table" => self::table,
					"field" => $field,
					"where" => $where,
				]);
			}
			if (in_array($json['warn'], ["新增成功", "更新成功"])) {
				//添加日志
				$type = mb_substr($json['warn'], 0, 2, 'utf-8');
				$text = $this->control['name'] . $type . "了" . self::title . " id：【" . $id . '】';
				$this->logText(["type" => self::page, "text" => $text]);
				//返回
				$_SESSION['warn'] = $json['warn'];
				$json['warn']     = 2;
				$json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $id;
			}
		}

		resp:
		return json_encode($json, 320);
	}
    /**
     * 判断是否和车辆使用时间是否有重合
     */
    public function is_cross($startTime, $endTime, $carId): bool|array
    {
        $flag = false;
        //还未开始使用的会议室
        $obj = new workSignCheckClass();
        $result = find(array('table' => self::table, 'where' => " carId = '$carId' and state !='草稿' and isBack = '否' order by time desc"));
        foreach ($result['array'] as $array) {
            $bool = $obj->timeBetween($startTime, $endTime, $array['startDate'], $array['endDate']);
            if ($bool['isBetween'] || $array['startDate'] == $endTime) {
                $flag = true;
                break;
            }
        }
        return $flag;
    }

    /**
     * 提交审批前的验证方法
     */
    public function commitBefore($data): bool|string
    {
        $info = query(self::table,"id = '$data[id]'");
        if ($this->is_cross($info['startDate'], $info['endDate'], $info['carId'])) {
            //判断提交时间是否和已申请的会员室时间存在重合
            return '您所提交的使用时间和其他人有重合';
        }
        return true;
    }
	/**
	 * 审核按钮
	 *
	 * @param $info
	 * @return array
	 */
	public function auditButton($info): array
	{
		$button = [];
		if ($info['state'] == '草稿' || auditClass::auditFlag(self::table, $info['id'],'selfChoose')) {
			$button[] = [
				"name"  => '提交审批',
				"type"  => "弹出层",
				"cla"   => 'audit',
				"fun"   => "operate",
				'style' => 'li-btn-blue-bg',
				"post"  => [
					"act" => 'start', "id" => $info['id'], 'body' => self::encryptDecrypt(json_encode([
						'name'    => '用车申请',
						'table'   => self::table,
						'process' => [
							// 预览函数
							'detail' => [
								'cla' => $this->get('cla'),
								'fun' => 'detail',
							],
							//执行发起时验证函数
							'before' => [
								'cla' => $this->get('cla'),
								'fun' => 'commitBefore',
                                'data'=>['id'=>$info['id']]
							],
							//完成发起后执行函数
							'after'  => [
								'cla' => $this->get('cla'),
								'fun' => '',
							],
						],
					], 320)),
				],
			];
		}
		// 审批并判断是否有权限
		if ($info['state'] == '审核中' && auditClass::auditFlag(self::table, $info['id'])) {
			$button[] = [
				"name" => '添加审批人',
				"type" => "弹出层",
				"cla"  => 'audit',
				"fun"  => "operate",
				"post" => [
					"act" => 'addApprover', "id" => $info['id'], 'body' => self::encryptDecrypt(json_encode([
						'table' => self::table,
					], 320)),
				],
			];
			$button[] = [
				"name" => '转交',
				"type" => "弹出层",
				"cla"  => 'audit',
				"fun"  => "operate",
				"post" => [
					"act" => 'transfer', "id" => $info['id'], 'body' => self::encryptDecrypt(json_encode([
						'table' => self::table,
					], 320)),
				],
			];
			$button[] = [
				"name"  => '审批',
				"type"  => "弹出层",
				"cla"   => 'audit',
				"fun"   => "operate",
				// 以下参数固定格式
				"post"  => [
					"act" => 'approval', "id" => $info['id'], 'body' => self::encryptDecrypt(json_encode([
						'table'   => self::table,
						// 当前状态
						'state'   => $info['state'],
						// 变更
						'field'   => ['state'],   //变更字段 可多个
						'value'   => [
							'state' => ['草稿', '已通过'],
						],
						// 审核时回调
						'process' => [
							//执行首次审核时验证
							'before' => [
								'cla' => $this->get('cla'),
								'fun' => '',
							],
							//执行末次审核后处理
							'after'  => [
								'cla' => $this->get('cla'),
								'fun' => '',
							],
						],
					], 320)),
				],
				'style' => 'li-btn-blue-bg',
			];
		}

		// 撤销审批
		if (auditClass::auditFlag(self::table, $info['id'], 'cancel') && $info['state'] != '草稿') {
			$button[] = [
				"name" => '撤销审批',
				"type" => "弹出层",
				"cla"  => 'audit',
				"fun"  => "operate",
				"post" => [
					"act" => 'cancel', "id" => $info['id'], 'body' => self::encryptDecrypt(json_encode([
						'table'   => self::table,
						// 当前状态
						'state'   => $info['state'],
						// 变更
						'field'   => ['state'],   //变更字段 可多个
						'value'   => [
							'state' => ['草稿'],
						],
						'process' => [
							//完成发起后执行函数
							'after' => [
								'cla' => $this->get('cla'),
								'fun' => '',
							],
						],
					], 320)),
				],
			];
		}
		return $button;
	}

	/*详情页*/
	public function detail(): string
	{
		$info = query(self::table, " id = '{$this->get('id')}'");
		if (empty($info['id'])) {
			$html = '未找到此' . self::title;
		} else {
			//菜单
			$data = array(
				"id"    => $info['id'],
				"title" => self::title . '详情',
			);

			$button = [];
			if ($this->power(self::page, "edit") && $info['state'] == '草稿') {
				//按钮
				$button[] = [
					"name"  => "编辑",
                    "type" => "弹出层",
                    "cla" => $this->get('cla'),
                    "fun" => "edit",
                    "post" => ["id" => $info['id']],
				];

			}
            if ($this->power(self::page, "del") && $info['state'] == '草稿') {
                //按钮
                $button[] = [
                    "name" => "删除",
                    "type" => "弹出层",
                    "cla"  => $this->get('cla'),
                    "fun"  => "operate",
                    "post" => ["act" => 'del', "id" => $info['id']],
                ];
            }
			//审核按钮
			$button = array_merge($this->auditButton($info),$button);

			$job        = query('job', " id = '$info[jobId]'");
			$department = query('department', " id = '$job[departmentId]'");
			$car        = query('car', " id = '$info[carId]'");
			$audit      = query('audit', " targetId = '$info[id]'");
            $backField = array(
                array(
                    "实际还车时间" => $info['backDate'],
                    "实际里程" => $info['factMileage'],
                    "还车备注"  => $info['backText'],
                )
            );
			//生成表单
            $data['button'] = $this->tableShowButton($button);
			$data['html'] = $this->tableShow(array(
                '详细信息'=>array(
					array(
						"用车人部门" => $department['name'],
						"用车人"   => self::findStaff($info['staffId']),
						"用车时间"  => $info['startDate'],
                        "还车时间" => $info['endDate'],
					),
					array(
                        "车牌号"  => $car['shortName'] . $car['carNo'],
						"出车线路"  => $info['lineStart'],
						"返程线路"  => $info['lineEnd'],
						"公里数合计" => $info['kilometre'],
					),
					array(
						"用车事由" => $info['reason'],
					),
				),
				'还车信息'=>$backField,
				'系统信息'   => array(
					array(
						"单据编号" => $info['orderNo'],
						"申请部门" => $info['deptName'],
						"申请人"  => self::findStaff($info['stid']),
                        "创建时间" => $info['time'],
					),
					array(
						"提交时间" => self::null($audit['commitTime']),
						'状态'   => $info['state'],
					),
				),
				'流程'     => array(
					array(
						auditClass::auditRecord(self::table, $info['id']),
					),
				),
			));
			//生成页面
			$html = $this->tab($data);
		}
		//返回
		return $html;
	}

	// 操作中转
	public function operate()
	{
		$act  = $this->post('act') ?? '';
		$pwd  = false; // 需要密码
		$form = $power = '';
		switch ($act) {
			default:
				$act      = 'del';
				$msg      = '删除' . self::title;
				$title    = self::page . 'Delete';
				$function = 'delete';
				$form     = self::page . 'OperateForm, listForm';
				$power    = '';
				break;
		}
		if (!$this->power(self::page, $act)) {
			$_SESSION['warn'] = '你还没有' . $msg . '的权限';
			$json             = [
				'warn' => 2,
				'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
			];
		} else {
			return $this->confirm([
				'title'    => $title,
				'function' => $function,
				'form'     => $form,
				'power'    => $power,
				'pwd'      => $pwd,
			]);
		}

		resp:
		return json_encode($json, 320);
	}

	/**
	 * 删除
	 *
	 * @return bool|string
	 */
	public function delete()
	{
		$array = $this->post('listId') ?? $this->post('id');
		if (!$this->power(self::page, "del")) {
			$json['warn'] = "你没有删除的权限";
		} elseif (empty($array)) {
			$json['warn'] = "你一个数据都没有选择呢";
		} else {
			$text  = "";
			$x     = 0;
			$array = is_array($array) ? $array : [$array];
			foreach ($array as $id) {
				$info = query(self::table, " id = '$id' ");
				if ($info['state'] != '草稿') {
					$warn = "不是草稿状态，暂不能删除";
				} else {
					//最后删除基本参数
					delete(array("table" => self::table, "where" => " id = '$id' "));
                    //删除audit表记录
                    delete(array('table' => 'audit', 'where' => "targetId = '$id'"));
                    //删除待办事项
                    delete(array("table" => "backlog","where" => " typeId = '$id' "));
                    //删除审批记录
                    delete(array("table" => "auditing_follow","where" => " typeId = '$id' "));
                    //删除消息提醒
                    delete(array("table" => "message","where" => " typeid = '$id' "));
					//返回
					$warn = "删除成功";
					$x++;
				}
				$text .= self::title . "ID【" . $info['id'] . "】" . $warn . "。<br>";
			}
			//添加日志
			$text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
			$this->logText(array("type" => self::page, "text" => $text));
			$_SESSION['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
			$json['warn']     = 2;
			$json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
		}
		return json_encode($json, 320);
	}
}

